package juc.util;

import java.util.concurrent.CountDownLatch;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

/**
 * CountDownLatch
 * 使用场景:
 * 场景1：让多个线程等待-模拟并发
 * 场景2：让单个线程等待:进行汇总合并
 */
public class CountDownLatchTest {

    public static void main(String[] args) throws InterruptedException {
        ScheduledExecutorService executorService = Executors.newScheduledThreadPool(10);
        //场景1：让多个线程等待-模拟并发
        //multiThreadWait(executorService);

        //场景2：让单个线程等待:进行汇总合并
        oneThreadWait(executorService);

        executorService.shutdown();

    }

    /**
     * 让单个线程等待
     * @param executorService
     * @throws InterruptedException
     */
    private static void oneThreadWait(ScheduledExecutorService executorService) throws InterruptedException {
        CountDownLatch countDownLatch = new CountDownLatch(5);
        for (int i = 0; i < 5; i++) {
            executorService.execute(()->{
                try {
                    System.out.println(Thread.currentThread().getName()+",开始运行...");
                    TimeUnit.SECONDS.sleep(2);
                    countDownLatch.countDown();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            });
        }

        // 主线程等待
        System.out.println(Thread.currentThread().getName()+",-------主线程等待---------");
        countDownLatch.await();
        System.out.println(Thread.currentThread().getName()+",-------执行完毕---------");
    }

    /**
     * 场景1：让多个线程等待-模拟并发
     *
     * @param executorService
     * @throws InterruptedException
     */
    private static void multiThreadWait(ScheduledExecutorService executorService) throws InterruptedException {
        CountDownLatch oneCountDown = new CountDownLatch(1);
        for (int i = 0; i < 5; i++) {
            executorService.execute(()->{
                try {
                    // 等待
                    oneCountDown.await();
                    System.out.println(Thread.currentThread().getName()+",开跑...");
                    TimeUnit.SECONDS.sleep(2);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }

            });
        }
        System.out.println(Thread.currentThread().getName()+",-------预备---------");
        TimeUnit.SECONDS.sleep(2);
        System.out.println(Thread.currentThread().getName()+",-------开始比赛---------");
        // 计数器减少
        oneCountDown.countDown();
    }

}
